﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Faust.Andrew.MTG.Player
{
	/// <summary>
	/// Interaction logic for CardListControl.xaml
	/// </summary>
    public partial class CardListControl : UserControl, ICardListView
	{
        public bool RemoveManually { get; set; }

        static CardListControl()
        {
            PresenterProperty = DependencyProperty.Register("Presenter", typeof(GamePresenter), typeof(CardListControl));
            CardListProperty = DependencyProperty.Register("CardList", typeof(ObservableCollection<Shared.GameCard>), typeof(CardListControl));
        }

        static DependencyProperty CardListProperty;
        public ObservableCollection<Shared.GameCard> CardList
        {
            get
            {
                return (ObservableCollection<Shared.GameCard>) base.GetValue(CardListProperty);
            }

            set
            {
                base.SetValue(CardListProperty, value);
            }
        }

        static DependencyProperty PresenterProperty;
        public GamePresenter Presenter
        {
            get
            {
                return (GamePresenter)base.GetValue(PresenterProperty);
            }
            set
            {
                base.SetValue(PresenterProperty, value);
            }
        }

		public CardListControl()
		{
			this.InitializeComponent();
		}
        
        public double Zoom
        {
            get { return sizeSlider.Value; }
            set
            {
                sizeSlider.Value = value;
            }
        }
        

        private void mnuPlay_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            PlayCard(card, false);            
        }

        private void mnuPlayFaceDown_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            PlayCard(card, true);            
        }

        //<MenuItem Header="Show Cards" Click="Cards_Show" />

        private void Cards_Show(object sender, System.Windows.RoutedEventArgs e)
        {            
            Presenter.Model.ShowCards(GetSelectedCards());
        }

        private List<Shared.GameCard> GetSelectedCards()
        {
            List<Shared.GameCard> cards = new List<Faust.Andrew.MTG.Player.Shared.GameCard>();

            foreach (object tempCard in lbHand.SelectedItems)
            {
                if (tempCard is Shared.GameCard)
                {
                    cards.Add(tempCard as Shared.GameCard);
                }
            }

            return cards;
        }

        private void Card_ToHand(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            //Presenter.Model.SendToHand(card);
            //RemoveFromList(card);
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToHand(cards);
            RemoveFromList(cards);
        }

        private void Card_ToDeckTop(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToDeck(cards, Shared.DeckPosition.Top, 0);
            RemoveFromList(cards);
        }

        private void Card_ToDeckBottom(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToDeck(cards, Shared.DeckPosition.Bottom, 0);
            RemoveFromList(cards);
        }

        private void Card_ToDeckRandom(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToDeck(cards, Shared.DeckPosition.Random, 0);
            RemoveFromList(cards);
        }

        private void Card_ToGraveyard(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToGraveyard(cards);
            RemoveFromList(cards);
        }

        private void Card_ToWorkspace(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            Presenter.Model.SendToWorkspace(cards);
            RemoveFromList(cards);
        }

        private void Card_ToDeckFromTop(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            string value = InputBox.ShowInput("How many places from the top should it be placed?", "0");
            int count;
            if (Int32.TryParse(value, out count))
            {
                Presenter.Model.SendToDeck(cards, Shared.DeckPosition.FromTop, count);
                RemoveFromList(cards);
            }
            else
            {
                MessageBox.Show("Invalid number");
            }
        }

        private void Card_ToDeckFromBottom(object sender, System.Windows.RoutedEventArgs e)
        {
            //Shared.GameCard card = lbHand.SelectedItem as Shared.GameCard;
            List<Shared.GameCard> cards = GetSelectedCards();
            string value = InputBox.ShowInput("How many places from the bottom should it be placed?", "0");
            int count;
            if (Int32.TryParse(value, out count))
            {
                Presenter.Model.SendToDeck(cards, Shared.DeckPosition.FromBottom, count);
                RemoveFromList(cards);
            }
            else
            {
                MessageBox.Show("Invalid number");
            }
        }

        private void spCards_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
        {
            if (sender is StackPanel)
            {
                StackPanel panel = sender as StackPanel;
                if (panel.ActualHeight > panel.ActualWidth)
                {
                    panel.Orientation = Orientation.Vertical;
                }
                else
                {
                    panel.Orientation = Orientation.Horizontal;
                }
            }
        }

        private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            FrameworkElement element = sender as FrameworkElement;
            if (element != null && element.DataContext is Shared.GameCard)
            {
                Presenter.PreviewCard((Shared.GameCard)element.DataContext);
            }
        }

        private void Cards_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            FrameworkElement element = (FrameworkElement)lbHand.InputHitTest(e.GetPosition(lbHand));

            while (element != null && element != lbHand)
            {
                if (element.DataContext is Shared.GameCard)
                {
                    Shared.GameCard card = element.DataContext as Shared.GameCard;
                    PlayCard(card, false);

                    return;
                }

                element = (FrameworkElement)VisualTreeHelper.GetParent(element);
            }
        }

        protected void PlayCard(Shared.GameCard card, bool isFaceDown)
        {
            if (card == null) { return; }

            card.IsFaceDown = isFaceDown;
            if (!Presenter.Model.PlayCard(card))
            {
                MessageBox.Show("Unable to play card");
            }
            else
            {
                RemoveFromList(card);
            }
        }

        protected void RemoveFromList(Shared.GameCard card)
        {
            if (RemoveManually && card != null)
            {
                CardList.Remove(card);
            }
        }

        private void RemoveFromList(List<Shared.GameCard> cards)
        {
            if (RemoveManually && cards != null)
            {
                foreach (Shared.GameCard card in cards)
                {
                    CardList.Remove(card);
                }
            }
        }

        private void CardList_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Presenter.PreviewMouseLeftButtonDown((FrameworkElement)sender, e, false);
        }

        private void CardList_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Presenter.PreviewMouseMove((FrameworkElement)sender, e, this);
        }

        private void CardList_PreviewDrop(object sender, System.Windows.DragEventArgs e)
        {
            Presenter.DropOnCardList(e);
        }

        private void CardList_PreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Presenter.PreviewMouseRightButtonDown((FrameworkElement)sender, e, false);
        }
    }
}